'''
Created on Jun 9, 2012

@author: TANDA


questions:

when printing bad line/rect format message, should lines start from  0 or 1? 
when encoutering illegal coordinate such as words etc, what message should we print ? the bad format of Illegal ret?
order of the processed images matters?
'''


import sys
import ctypes
import os

class CRect(ctypes.Structure):
    _fields_ = [    ("top"     , ctypes.c_int),
                    ("bottom"  , ctypes.c_int),
                    ("left"    , ctypes.c_int),
                    ("right"   , ctypes.c_int)
                ]
    
def get_all_rect_by_image_name(rect_file_name):
    f = open(rect_file_name, 'r');
    lines = f.readlines();
    
    line_number = 1
    
    rects = {}
    images_list = []
    
    for line in lines:
        tokens = line.split(' ')
        current_line_number = line_number
        line_number = line_number + 1
        
        if (len(tokens) != 5):
            sys.stderr.write('Bad format in line {!r}: Skipping.\n'.format(current_line_number))
            continue
        
        #get image name
        image_name = tokens[0]
            
        #get coords and check their validity

        try:
            coords = [int(x) for x in tokens[1:]]
        except: 
            sys.stderr.write('Bad format in line {!r}: Skipping.\n'.format(current_line_number))
            continue
            
        if ((coords[0] < 0) | (coords[2] < 0) | (coords[0] > coords[1]) | (coords[2] > coords[3])):
             sys.stderr.write('Illegal rectangle on line {!r}: {!r} {!r} {!r} {!r}\n'.format(current_line_number, coords[0], coords[1], coords[2], coords[3]))
             continue
            
        #add rect to the image's list
        if not rects.has_key(image_name):
            rects[image_name] = []
            images_list.append(image_name)
                
        rects[image_name].append(coords) 
            
            
        
    
    return rects, images_list
        
def rects_intersect(rects):
    bottom = 0
    top = 1
    left = 2
    right = 3
    
    for i in range(0, len(rects)):
        rect_a = rects[i]
        for j in range(i + 1, len(rects)):
            rect_b = rects[j]
            
            if not ((rect_a[left] > rect_b[right]) | (rect_a[right] < rect_b[left]) | (rect_a[top] < rect_b[bottom]) | (rect_a[bottom] > rect_b[top])):
                return True
            
    
    return False 
            
            
        
def verify_overlapping_rect(rects, images_list):
    
    seperate_rects = {}
    new_images_list = []
    
    for file_name in images_list:
        if not (rects_intersect(rects[file_name])):
            seperate_rects[file_name] = rects[file_name]
            new_images_list.append(file_name)
        else:
            sys.stderr.write('Rectangles for {!s} are overlapping\n'.format(file_name))
        
    return seperate_rects, new_images_list


def get_c_rect_arr(py_arr):
    
    c_rects = (CRect * len(py_arr))()
    
    index = 0
    for rect in py_arr:
        c_rects[index] = CRect(rect[0], rect[1], rect[2], rect[3])
        index = index + 1
        
    return c_rects
    
def blure_images(rects, images_list, blur_repetition):
        libbitmaps = ctypes.CDLL('./libbitmaps.so')
                                                 
        libbitmaps.bitmapblur.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.POINTER(CRect), ctypes.c_int, ctypes.c_int]
        
        libbitmaps.bitmapblur.restype = ctypes.c_int
        
        for file_name in images_list:
            out_file_name = os.path.join(os.path.dirname(file_name), 'blurred_' + os.path.basename(file_name))
            
            
            c_arr = get_c_rect_arr(rects[file_name]);
            c_ptr = ctypes.POINTER(CRect)()
            c_ptr = c_arr;
            
            res = libbitmaps.bitmapblur(file_name, out_file_name, c_ptr , len(rects[file_name]), blur_repetition)
            
            if (res != 0):
               sys.stderr.write('Error {!r} blurring bitmap {!s}\n'.format(res, file_name))
                 
if __name__ == '__main__':
    
    args = sys.argv[1:]
    
    if (len(args) != 2):
        print('Usage:\n\tpython2.7 ex4.py <rectangles file name> <blur repetitions>')
        sys.exit()
        
    rect_file_name = args[0];
    try:
        blur_repetition = int(args[1]);
    except:
        print('Usage:\n\tpython2.7 ex4.py <rectangles file name> <blur repetitions>')
        sys.exit()
    
    rects, images_list = get_all_rect_by_image_name(rect_file_name)
    
    rects, images_list = verify_overlapping_rect(rects, images_list);

    blure_images(rects, images_list, blur_repetition)
